package com.kathony.jangpa.b.tasks.impl;

import java.net.InetAddress;
import java.util.Date;
import java.util.HashMap;

import com.kathony.jangpa.b.config.LDConfig;
import com.kathony.jangpa.b.tasks.LDStatus;
import com.kathony.jangpa.b.tasks.exception.LDConfigException;

public class LDServerPing extends LDBaseTask {
	
	protected String destinationIp="127.0.0.1";
	protected int timeout=5000; //5 second
	protected int numberOfRequest=6; //6 times
	protected int timeBetweenRequest=2000; //2 second
	
	@Override 
	public void SetConfig(LDConfig config) throws LDConfigException{
		super.SetConfig(config);
		if(config.hasKey("destinationip")){
			this.destinationIp=config.getParams("destinationip");
		}
		if(config.hasIntKey("timeout")){
			this.timeout=config.getInt("timeout");
		}
		if(config.hasIntKey("numberofrequest")){
			this.numberOfRequest=config.getInt("numberofrequest");
		}
		if(config.hasIntKey("timebetweenrequest")){
			this.timeBetweenRequest=config.getInt("timebetweenrequest");
		}
	}
	
	@Override
	public void execute() {
		int successCount = 0;
		int failCount = 0;
		HashMap<String,Object> info = new HashMap<String,Object>();
		info.put("destinationip",this.destinationIp);
		info.put("timeout", this.timeout);
		info.put("numberofrequest",this.numberOfRequest);
		info.put("timebetweenrequest", this.timeBetweenRequest);
		
		for(int i=0;i<this.numberOfRequest;i++){
			try {
				InetAddress addr = InetAddress.getByName(this.destinationIp);
				if(addr.isReachable(this.timeout)){
					info.put("attempt_"+i, "OK");
					successCount++;
				}
				else {
					info.put("attempt_"+1, "fail");
					failCount++;
				}
				Thread.sleep(this.timeBetweenRequest);
			}
			catch (Exception e){
				info.put("attempt_"+1, "fail");
				info.put("attempt_"+i+"_error", e.getMessage());
				failCount++;
			}
		}
		info.put("success",successCount);
		info.put("fail", failCount);
		
		//generate status
		synchronized(this.lastStatus){
			LDStatus newStatus = new LDStatus();
			newStatus.setStatusCheckOk(successCount>=failCount? true:false);
			newStatus.setStatusCustomInfo(info);
			newStatus.setStatusDate(new Date());
			//TODO: set error code/error message here
		}
	}
	
	@Override
	public boolean shouldBeNotified(){
		synchronized(this.lastStatus){
			if(this.lastStatus.getStatusCheckOk()){
				return false;
			}
			else {
				return true;
			}
		}
	}
}
